package cn.tworice.cryption.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.util.Base64;

/**
 * DES 算法加解密工具类
 */
public class DESUtil {

    // 算法名称和工作模式
    private static final String ALGORITHM = "DES";
    private static final String TRANSFORMATION = "DES/ECB/PKCS5Padding";

    /**
     * DES 加密
     * @param data 明文数据
     * @param key  密钥（如果不足8字节，会自动补'='直到达到8字节）
     * @return 加密后的 Base64 编码字符串
     * @throws Exception 加解密过程中可能抛出的异常
     */
    public static String encrypt(String data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        SecretKey secretKey = generateKey(key);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] dataBytes = data.getBytes("UTF-8");
        byte[] encryptedBytes = cipher.doFinal(dataBytes);
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /**
     * DES 解密
     * @param encryptedData 加密后的 Base64 编码字符串
     * @param key           密钥（如果不足8字节，会自动补'='直到达到8字节）
     * @return 解密后的明文数据
     * @throws Exception 加解密过程中可能抛出的异常
     */
    public static String decrypt(String encryptedData, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        SecretKey secretKey = generateKey(key);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, "UTF-8");
    }

    /**
     * 根据给定的字符串密钥生成 DES 密钥，如果密钥不足8字节则补'='直到达到8字节
     * @param key 密钥字符串
     * @return SecretKey 对象
     * @throws Exception 密钥生成失败时抛出异常
     */
    private static SecretKey generateKey(String key) throws Exception {
        // 将 key 转为字节数组
        byte[] keyBytes = key.getBytes("UTF-8");
        if (keyBytes.length < 8) {
            // 补足'='字符，直到达到8字节
            int padLength = 8 - keyBytes.length;
            StringBuilder sb = new StringBuilder(key);
            for (int i = 0; i < padLength; i++) {
                sb.append("=");
            }
            key = sb.toString();
        }
        // 如果超过8字节，截取前8字节
        if (key.getBytes("UTF-8").length > 8) {
            key = new String(key.getBytes("UTF-8"), 0, 8);
        }
        // 使用处理后的 key 创建 DESKeySpec
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        return keyFactory.generateSecret(desKeySpec);
    }
}
